// Copyright (c) Huawei Technologies Co., Ltd. 2023-2024. All rights reserved.
// licensed under the Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of Mulan PSL v2 at:
//      http://license.coscl.org.cn/MulanPSL2
// THIS SOFTWARE IS PROVIDED ON AN 'AS IS' BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
// PURPOSE.
// See the Mulan PSL v2 for more details.
import type { Direction, DistributionParams, PageNation, Sort } from '../types'
import type {
  AffectedHost,
  Cve,
  CveCount,
  CveDetail,
  CveFixInfo,
  CveRollbackInfo,
  CveRollbackTaskReport,
  Host,
  HostDetail,
  HotPatchInfo,
  HotPatchRemoveTaskReport,
  QueryCvesParams,
  QueryCvesWithHostParams,
  QueryHostWithIdParams,
  QueryTasksHostsParams,
  QueryTasksParams,
  Repo,
  RepoSetInfo,
  RepoTaskReport,
  Rpm,
  Task,
  TaskDetail,
  TaskStatus,
  generateCveFixTaskParams,
  generateCveHotPatchTaskParams,
  generateRepoSetTaskParams,
} from './types'
import { http } from '@/api/request'

// #region ------------------------------------ < distribution > ------------------------------------
/**
 * create a cve fix task
 * @param params
 */
function generateCveFixTask(params: generateCveFixTaskParams) {
  return http.post<Record<string, { data: { fix_way: string, task_id: string }[], label: string }>>(
    '/distribute/vulnerabilities/task/cve-fix/generate',
    params,
  )
}
/**
 * create a hot patch remove task
 * @param params
 */
function generateCveHotPatchTask(params: generateCveHotPatchTaskParams) {
  return http.post<Record<string, { data: { task_id: string }[], label: string }>>(
    '/distribute/vulnerabilities/task/hotpatch-remove/generate',
    params,
  )
}
/**
 * generate cve rollback task
 * @param params
 */
function generateCveRollbackTask(params: DistributionParams<{ fix_task_id: string }>) {
  return http.post<{
    task_id: string
  }>('/distribute/vulnerabilities/task/cve-rollback/generate', params)
}
function generateRepoSetTask(params: DistributionParams<generateRepoSetTaskParams>) {
  return http.post<Record<string, {
    data: { task_id: string }
    label: string
  }>>('/distribute/vulnerabilities/task/repo/generate', params)
}
/**
 * scan host val
 * @param params
 */
function scanHost(params: DistributionParams<{ host_list: string[] }>) {
  return http.post('/distribute/vulnerabilities/host/scan', params)
}
/**
 * delete task by host ids
 * @param params
 */
function deleteTasks(params: DistributionParams<{ task_list: string[] }>) {
  return http.delete<Record<string, {
    data: {
      running_task: string[]
    }
    label: string
  }>>('/distribute/vulnerabilities/task/delete', params)
}
/**
 * execute task by task id
 * @param params
 */
function executeTask(params: DistributionParams<{ task_id: string }>) {
  return http.post<Record<string, {
    data: { task_id: string }
    label: string
  }>>('/distribute/vulnerabilities/task/execute', params)
}

function getCveFixTaskResult(params: DistributionParams<{ task_id: string }>) {
  return http.post<RepoTaskReport[]>('/distribute/vulnerabilities/task/cve-fix/result/get', params)
}

function getCveRollbackTaskResult(params: DistributionParams<{ task_id: string }>) {
  return http.post<CveRollbackTaskReport[]>(
    '/distribute/vulnerabilities/task/cve-rollback/result/get',
    params,
  )
}
function getHotPatchRemoveTaskResult(params: DistributionParams<{ task_id: string }>) {
  return http.post<HotPatchRemoveTaskReport[]>(
    '/distribute/vulnerabilities/task/hotpatch-remove/result/get',
    params,
  )
}
function getRepoSetTaskResult(params: DistributionParams<{ task_id: string }>) {
  return http.post<RepoTaskReport[]>('/distribute/vulnerabilities/task/repo/result/get', params)
}

function createNewRepo(params: DistributionParams<{ repo_name: string, repo_data: string }>) {
  return http.post('/distribute/vulnerabilities/repo/import', params)
}

function deleteRepo(params: DistributionParams<{ repo_id_list: string[] }>) {
  return http.delete<Record<string, { data: any, label: string }>>('/distribute/vulnerabilities/repo/delete', params)
}
// #endregion
function downLoadRepoTemplate() {
  return http.get('/vulnerabilities/repo/template/get', { responseType: 'blob' })
}

/**
 * query cve count in all cve level
 */
function getCveOverview() {
  return http.get<CveCount>('/vulnerabilities/cve/overview')
}
/**
 * get cves
 * @param params
 */
function getCves(params: QueryCvesParams) {
  return http.post<{
    result: Cve[]
    total_count: number
    total_page: number
  }>('/vulnerabilities/cve/list/get', params)
}
/**
 * get hosts in cves
 */
function getHostsInCves(params: {
  cve_list: {
    cve_id: string
    rpms: { available_rpm: string, fix_way: string, installed_rpm: string }[]
  }[]
  fixed: boolean
  host_list?: string[]
}) {
  return http.post<{
    result: Record<
      string,
      {
        package: string
        hosts: {
          host_id: string | number
          host_ip: string
          hotpatch?: boolean
          host_name: string
          cluster_id: string
          cluster_name: string
        }[]
      }
    >[]
  }>('/vulnerabilities/cve/task/host/get', params)
}

function getUnfixedRpm(params: { cve_id: string, host_ids: string[] }) {
  return http.post<Rpm[]>('/vulnerabilities/cve/unfixed/packages/get', params)
}

function getFixedRpm(params: { cve_id: string, host_ids: string[] }) {
  return http.post<Rpm[]>('/vulnerabilities/cve/fixed/packages/get', params)
}

function getCveInfos(cveId: string) {
  return http.get<{
    result: CveDetail
  }>('/vulnerabilities/cve/info/get', { params: { cve_id: cveId } })
}

/**
 * Query the hosts affected by the vulnerabilities
 * @params
 * {
 *    cve_id: string
 *    page: number
 *    per_page: number
 *    filter:
 *      fixed:boolean
 *      host_group?: string[]
 *      host_name?: string
 *      repo?: string[]
 *    sort?: string
 *    direction?: 'asc' | 'desc'
 * }
 */
function getHostsByCveId(params: QueryHostWithIdParams) {
  return http.post<{
    result: AffectedHost[]
    total_count: number
    total_page: number
  }>('/vulnerabilities/cve/host/get', params)
}

function exportCveInfo(hostList: string[]) {
  return http.post('/vulnerabilities/cve/info/export', { host_list: hostList }, { responseType: 'blob' })
}

/**
 * get host list in vulnerabilities
 * @param params
 */
function getCveHosts(params: {
  filter: {
    host_name?: string
    host_group_ids?: string[]
    repo?: string[]
    cluster_list?: string[]
  }
} & Partial<PageNation> &
Partial<Sort>) {
  return http.post<{
    result: Host[]
    total_count: number
    total_page: number
  }>('/vulnerabilities/host/list/get', params)
}
/**
 * get host status in val
 * @param hostList
 */
function getHostStatus(hostList: string[]) {
  return http.post<{
    result: Record<string, number>
  }>('/vulnerabilities/host/status/get', { host_list: hostList })
}

function getCveRepoList(list?: string[], searchkey?: string) {
  return http.post<Repo[]>('/vulnerabilities/repo/get', {
    repo_id_list: list,
    search_key: searchkey,
  })
}

function getHostInfo(hostId: string) {
  return http.get<HostDetail>('/vulnerabilities/host/info/get', { params: { host_id: hostId } })
}

function getCvesWithHost(params: QueryCvesWithHostParams) {
  return http.post<{
    result: Cve[]
    total_count: number
    total_page: number
  }>('/vulnerabilities/host/cve/get', params)
}

function getHostsWithPackage(params: {
  direction: Direction
  cve_id: string
  installed_rpm: string
  available_rpm: string
  hp_status?: string
  fixed: boolean
  host_ids?: string[]
}) {
  return http.post<{
    result: {
      host_ip: string
      host_name: string
    }[]
    total_page: number
    total_count: number
  }>('/vulnerabilities/cve/packages/host/get', params)
}

function getTasks(params: QueryTasksParams) {
  return http.post<{
    result: Task[]
    total_page: number
    total_count: number
  }>('/vulnerabilities/task/list/get', params)
}

function getTasksStatus(taskIds: string[]) {
  return http.post<{
    result: {
      [key in string]: TaskStatus;
    }
  }>('/vulnerabilities/task/progress/get', { task_list: taskIds })
}

function getTaskDetailInfo(taskId: string) {
  return http.get<TaskDetail>('/vulnerabilities/task/info/get', { params: { task_id: taskId } })
}

/**
 * get hosts in cve fix task
 * @param params
 */
function getCveFixInfo(params: QueryTasksHostsParams) {
  return http.post<{
    result: CveFixInfo[]
    total_page: number
    total_count: number
  }>('/vulnerabilities/task/cve-fix/info/get', params)
}

function getCveFixRpm(hostId: string, taskId: string) {
  return http.post<Rpm[]>('/vulnerabilities/task/cve-fix/rpm/get', {
    host_id: hostId,
    task_id: taskId,
  })
}
/**
 * get hot patch remove info
 * @param params
 */
function getHotPatchInfo(params: { task_id?: string, filter: { cve_id?: string, status?: string[] } } & PageNation &
  Partial<Sort>) {
  return http.post<{
    result: HotPatchInfo[]
    total_page: number
    total_count: number
  }>('/vulnerabilities/task/hotpatch-remove/info/get', params)
}
/**
 * get cve rollback remove info
 * @param params
 */
function getCveRollbackInfo(params: { task_id?: string, filter: { search_key?: string, status?: string[] } } & PageNation) {
  return http.post<{
    result: CveRollbackInfo[]
    total_page: number
    total_count: number
  }>('/vulnerabilities/task/cve-rollback/info/get', params)
}
/**
 * get repo set info
 * @param params
 */
function getRepoSetInfo(params: { task_id?: string, filter: { host_name?: string, status?: string[] } } & PageNation) {
  return http.post<{
    result: RepoSetInfo[]
    total_page: number
    total_count: number
  }>('/vulnerabilities/task/repo/info/get', params)
}
/**
 *
 * @param hostId
 * @param taskId
 */
function getCveRollbackRpm(hostId: string, taskId: string) {
  return http.post<Rpm[]>(
    '/vulnerabilities/task/cve-rollback/rpm/get',
    {
      host_id: hostId,
      task_id: taskId,
    },
  )
}

function uploadSAAffected(file: FormData) {
  return http.post('/vulnerabilities/cve/advisory/upload', file)
}
function uploadSAUnAffected(file: FormData) {
  return http.post('/vulnerabilities/cve/unaffected/upload', file)
}

export * from './types'
export const vulnerabilityApi = {
  getCveOverview,
  getCves,
  getUnfixedRpm,
  getFixedRpm,
  getCveInfos,
  getHostsByCveId,
  getCveHosts,
  getCveRepoList,
  getHostInfo,
  getCvesWithHost,
  getHostsWithPackage,
  getTasks,
  getTasksStatus,
  getTaskDetailInfo,
  getCveFixInfo,
  getCveFixRpm,
  getCveFixTaskResult,
  getCveRollbackTaskResult,
  deleteTasks,
  uploadSAAffected,
  uploadSAUnAffected,
  getHostsInCves,
  generateCveFixTask,
  generateCveHotPatchTask,
  getHostStatus,
  scanHost,
  exportCveInfo,
  executeTask,
  generateCveRollbackTask,
  getHotPatchInfo,
  getCveRollbackInfo,
  getCveRollbackRpm,
  generateRepoSetTask,
  createNewRepo,
  downLoadRepoTemplate,
  getRepoSetInfo,
  deleteRepo,
  getRepoSetTaskResult,
  getHotPatchRemoveTaskResult,
}
